home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1996 #15 / Monster Media Number 15 (Monster Media)(July 1996).ISO / bbs_util / bsrc_260.zip / SRC.ZIP / MISC.C < prev    next >
C/C++ Source or Header  |  1996-03-23  |  32KB  |  1,521 lines

  1. /*--------------------------------------------------------------------------*/
  2. /*                                                                          */
  3. /*                                                                          */
  4. /*      ------------         Bit-Bucket Software, Co.                       */
  5. /*      \ 10001101 /         Writers and Distributors of                    */
  6. /*       \ 011110 /          Freely Available<tm> Software.                 */
  7. /*        \ 1011 /                                                          */
  8. /*         ------                                                           */
  9. /*                                                                          */
  10. /*              (C) Copyright 1987-96, Bit Bucket Software Co.              */
  11. /*                                                                          */
  12. /*                This module was written by Vince Perriello                */
  13. /*                     with code from several authors                       */
  14. /*                Miscellaneous routines used by BinkleyTerm                */
  15. /*                                                                          */
  16. /*                                                                          */
  17. /*    For complete  details  of the licensing restrictions, please refer    */
  18. /*    to the License  agreement,  which  is published in its entirety in    */
  19. /*    the MAKEFILE and BT.C, and also contained in the file LICENSE.260.    */
  20. /*                                                                          */
  21. /*    USE  OF THIS FILE IS SUBJECT TO THE  RESTRICTIONS CONTAINED IN THE    */
  22. /*    BINKLEYTERM  LICENSING  AGREEMENT.  IF YOU DO NOT FIND THE TEXT OF    */
  23. /*    THIS  AGREEMENT IN ANY OF THE  AFOREMENTIONED FILES,  OR IF YOU DO    */
  24. /*    NOT HAVE THESE FILES,  YOU  SHOULD  IMMEDIATELY CONTACT BIT BUCKET    */
  25. /*    SOFTWARE CO.  AT ONE OF THE  ADDRESSES  LISTED BELOW.  IN NO EVENT    */
  26. /*    SHOULD YOU  PROCEED TO USE THIS FILE  WITHOUT HAVING  ACCEPTED THE    */
  27. /*    TERMS  OF  THE  BINKLEYTERM  LICENSING  AGREEMENT,  OR  SUCH OTHER    */
  28. /*    AGREEMENT AS YOU ARE ABLE TO REACH WITH BIT BUCKET SOFTWARE, CO.      */
  29. /*                                                                          */
  30. /*                                                                          */
  31. /* You can contact Bit Bucket Software Co. at any one of the following      */
  32. /* addresses:                                                               */
  33. /*                                                                          */
  34. /* Bit Bucket Software Co.        FidoNet  1:104/501, 1:343/491             */
  35. /* P.O. Box 460398                AlterNet 7:42/1491                        */
  36. /* Aurora, CO 80046               BBS-Net  86:2030/1                        */
  37. /*                                Internet f491.n343.z1.fidonet.org         */
  38. /*                                                                          */
  39. /* Please feel free to contact us at any time to share your comments about  */
  40. /* our software and/or licensing policies.                                  */
  41. /*                                                                          */
  42. /*--------------------------------------------------------------------------*/
  43.  
  44. /* Include this file before any other includes or defines! */
  45.  
  46. #include "includes.h"
  47.  
  48. #define EVENT_ENABLE
  49.  
  50. #ifdef Snoop
  51. #include "snserver.h"
  52. extern HSNOOP hsnoop;
  53. #endif                            /* Snoop */
  54.  
  55. static char newstring[200];
  56. static void LOCALFUNC fill_in_status (char *);
  57. static int LOCALFUNC find_addr (char *, ADDR *, char *);
  58.  
  59. int 
  60. set_baud (unsigned long baudrate, int log)
  61. {
  62.     register int i;
  63.     unsigned long search_rate;
  64.  
  65.     search_rate = (baudrate > max_baud.rate_value) ? max_baud.rate_value : baudrate;
  66.  
  67.     for (i = 0; pbtypes[i].rate_value; i++)
  68.     {
  69.         if (pbtypes[i].rate_value >= search_rate)
  70.         {
  71.             if ((pbtypes[i].rate_value != search_rate) && (search_rate <= 2400))
  72.                 break;
  73.  
  74.             if (baud != i)        /* same as what we have?     */
  75.             {
  76.                 if (log && !un_attended)
  77.                     status_line (MSG_TXT (M_SETTING_BAUD), baudrate);
  78.                 baud = i;        /* need this for ALT-B       */
  79.                 program_baud ();
  80.                 cur_baud = pbtypes[i];
  81.             }
  82.  
  83.             cur_baud.rate_value = baudrate;
  84.  
  85.             if (un_attended && fullscreen)
  86.             {
  87.                 (void) sprintf (junk, "%-6lu Com%d", baudrate, port_ptr + 1);
  88.                 sb_move (settingswin, SET_PORT_ROW, SET_COL);
  89.                 sb_puts (settingswin, junk);
  90.                 sb_show ();
  91.             }
  92.             return (1);
  93.         }
  94.     }
  95.     return (0);
  96. }
  97.  
  98. void 
  99. program_baud ()
  100. {
  101.     unsigned long rate_mask;
  102.  
  103.     set_prior (4);                /* Always High    */
  104.  
  105.     if ((lock_baud && (pbtypes[baud].rate_value >= lock_baud))
  106.         || (ARQ_lock != 0))
  107.         rate_mask = max_baud.rate_mask;
  108.     else
  109.         rate_mask = pbtypes[baud].rate_mask;
  110.  
  111.     MDM_ENABLE (rate_mask);
  112.  
  113.     set_prior (2);                /* Regular        */
  114.  
  115. }
  116.  
  117. static char *specifiers = "!*+:# >";
  118. static struct tm *tp;
  119. static time_t ltime;
  120.  
  121. void _cdecl 
  122. status_line (char *fmt,...)
  123. {
  124.     va_list arg_ptr;
  125.  
  126.     char tmp[255];
  127.  
  128.     va_start (arg_ptr, fmt);
  129.     if (fmt == NULL)
  130.         return;
  131.     (void) vsprintf (e_input, fmt, arg_ptr);
  132.     (void) time (<ime);
  133.     tp = localtime (<ime);
  134.     if ((!fullscreen) || (!un_attended))
  135.     {
  136.         if ((e_input[0] != '>') || debugging_log)
  137.         {
  138.             (void) sprintf (tmp, "\r\n%c %02i %03s %02i:%02i:%02i " PRDCT_SHRT " %s", e_input[0],
  139.                 tp->tm_mday, mtext[tp->tm_mon], tp->tm_hour, tp->tm_min, tp->tm_sec,
  140.                 &e_input[1]);
  141.             scr_printf (tmp);
  142.         }
  143.     }
  144.     else
  145.     {
  146.         if ((e_input[0] != '>') || debugging_log)
  147.         {
  148.             (void) sprintf (tmp, stat_str, e_input[0],
  149.                 tp->tm_hour, tp->tm_min, tp->tm_sec, &e_input[1]);
  150.  
  151.             fill_in_status (tmp);
  152.  
  153. #ifdef Snoop
  154.             if (hsnoop != (HSNOOP) 0L)
  155.                 (void) SnoopWrite (hsnoop, (PSZ) tmp);
  156. #endif                            /* Snoop */
  157.         }
  158.     }
  159.     if ((status_log != NULL) &&
  160.         ((strchr (specifiers, e_input[0]) - strchr (specifiers, '!')) <= loglevel))
  161.     {
  162.         (void) fprintf (status_log, "%c %02i %s %02i:%02i:%02i BINK %s\n", e_input[0],
  163.             tp->tm_mday, mtext[tp->tm_mon], tp->tm_hour, tp->tm_min, tp->tm_sec,
  164.             &e_input[1]);
  165.         if (immed_update)
  166.         {
  167.             (void) fflush (status_log);
  168.             (void) real_flush (fileno (status_log));
  169.             need_update = 0;
  170.         }
  171.         else
  172.         {
  173.             need_update = 1;
  174.         }
  175.     }
  176.     va_end (arg_ptr);
  177. }
  178.  
  179. /*--------------------------------------------------------------------------*/
  180. /* THROUGHPUT                                                               */
  181. /* Print throughput message at end of transfer                              */
  182. /*--------------------------------------------------------------------------*/
  183. long 
  184. throughput (int opt, unsigned long bytes)
  185. {
  186.     static long started = 0L;
  187.     static long elapsed = 0L;
  188.     static long cps;
  189.  
  190.     if (!opt)
  191.         started = time (NULL);
  192.     else if (started)
  193.     {
  194.         elapsed = time (NULL);
  195.         /* The next line tests for day wrap without the date rolling over */
  196.         if (elapsed < started)
  197.             elapsed += 86400L;
  198.         elapsed -= started;
  199.         if (elapsed == 0L)
  200.             elapsed = 1L;
  201.         cps = (long) (bytes / (unsigned long) elapsed);
  202.         started = (cps * 1000L) / ((long) cur_baud.rate_value);
  203.         status_line ((char *) MSG_TXT (M_CPS_MESSAGE), cps, bytes, started);
  204.     }
  205.     return elapsed;
  206. }                                /* throughput */
  207.  
  208. static void LOCALFUNC 
  209. fill_in_status (char *stat_line)
  210. {
  211.     int     i;
  212.  
  213.     (void) time (<ime);
  214.     tp = localtime (<ime);
  215.     if (fullscreen && callwin)/*PLF Sun  12-01-1991  07:25:27 */
  216.     {
  217.         if (strlen (callwin->endbuff)) 
  218.             memmove (callwin->buffer, 
  219.                 callwin->buffer + callwin->linesize, 
  220.                 callwin->endbuff - callwin->buffer);
  221.         else if (strlen (callwin->buffer))
  222.         {
  223.             callwin->lastshown += callwin->linesize;
  224.             callwin->lastline += callwin->linesize;
  225.         }
  226.  
  227.         i = min (strlen (stat_line) + 1, (unsigned int)callwin->linesize);
  228.         memmove (callwin->lastline, stat_line, i);
  229.         callwin->lastline[i-1] = 0x00;
  230.  
  231.         sb_scrl (callwin, 1);
  232.  
  233.         sb_move (callwin, SB_ROW_STATUS, 2);
  234.         sb_puts (callwin, callwin->lastshown);
  235.  
  236.         (void) sprintf (junk, "%s %s %02d @ %02d:%02d",
  237.             wkday[tp->tm_wday], mtext[tp->tm_mon], tp->tm_mday,
  238.             tp->tm_hour, tp->tm_min);
  239.         sb_move (settingswin, SET_TIME_ROW, SET_TIME_COL);
  240.         sb_puts (settingswin, junk);
  241.         sb_show ();
  242.     }
  243. }
  244.  
  245. void 
  246. set_xy (char *string)
  247. {
  248.     WRITE_ANSI ('\r');
  249.     WRITE_ANSI ('\n');
  250.     scr_printf (string);
  251.     locate_x = wherex ();
  252.     locate_y = wherey ();
  253. }
  254.  
  255. void _cdecl 
  256. time_release ()
  257. {
  258.     EventSub ();
  259.     if (need_update)
  260.     {
  261.         if (status_log != NULL)    /*WRA*/
  262.         {
  263.             (void) fflush (status_log);
  264.             (void) real_flush (fileno (status_log));
  265.         }
  266.         need_update = 0;
  267.     }
  268.  
  269.     dos_break_off ();            /* Turn off ^C trapping */
  270.  
  271.     (*mtask_idle) ();
  272.  
  273. }
  274.  
  275. char *
  276. fancy_str (char *string)
  277. {
  278.     register int flag = 0;
  279.     char *s;
  280.  
  281.     s = string;
  282.  
  283.     while (*string)
  284.     {
  285.         if (isalpha (*string))    /* If alphabetic,     */
  286.         {
  287.             if (flag)            /* already saw one?   */
  288.                 *string = (char) tolower (*string);    /* Yes, lowercase it  */
  289.             else
  290.             {
  291.                 flag = 1;        /* first one, flag it */
  292.                 *string = (char) toupper (*string);    /* Uppercase it       */
  293.             }
  294.         }
  295.         else                    /* if not alphabetic  */
  296.             flag = 0;            /* reset alpha flag   */
  297.         string++;
  298.     }
  299.  
  300.     return (s);
  301. }
  302.  
  303. void 
  304. timer (int interval)
  305. {
  306.     long timeout;
  307.  
  308.     timeout = timerset ((unsigned int) (interval * 10));
  309.     while (!timeup (timeout))
  310.         time_release ();
  311. }
  312.  
  313. void 
  314. big_pause (int secs)
  315. {
  316.     long timeout;
  317.  
  318.     timeout = timerset ((unsigned int) (secs * 100));
  319.     while (!timeup (timeout))
  320.     {
  321.         if (CHAR_AVAIL ())
  322.             break;
  323.         time_release ();
  324.     }
  325. }
  326.  
  327. void 
  328. scr_printf (char *string)
  329. {
  330.     if (string != NULL)
  331.         if (vfossil_installed)
  332.             (void) VioWrtTTY ((PCH) string, (USHORT) strlen (string), (HVIO) 0L);
  333.         else
  334.             while (*string != 0)
  335.                 WRITE_ANSI (*string++);
  336. }
  337.  
  338. void 
  339. send_can ()
  340. {
  341.     int i;
  342.  
  343.     CLEAR_OUTBOUND ();
  344.     CLEAR_INBOUND ();
  345.  
  346.     for (i = 0; i < 10; i++)
  347.         SENDBYTE (CAN);
  348.     for (i = 0; i < 10; i++)
  349.         SENDBYTE (BS);
  350. }
  351.  
  352. void 
  353. invent_pkt_name (char string[])
  354. {
  355.     struct tm *ptm;
  356.     time_t lTimeT;
  357.  
  358.     (void) time (&lTimeT);
  359.     ptm = localtime (&lTimeT);
  360.     (void) sprintf (string, "%02i%02i%02i%02i.pkt",
  361.         ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
  362. }
  363.  
  364. static char *suffixes[8] =
  365. {
  366.     "SU", "MO", "TU", "WE", "TH", "FR", "SA", NULL
  367. };
  368.  
  369. int 
  370. is_user (char *p)
  371. {
  372.     char *q;
  373.     char far *r;
  374.     int i, j;
  375.  
  376.     if (cur_event < 0)
  377.         return (0);
  378.  
  379.     q = strchr (p, '.');
  380.     if (q != NULL)
  381.     {
  382.         ++q;
  383.         for (i = 0; i < 6; i++)
  384.         {
  385.             r = &(e_ptrs[cur_event].err_extent[i][0]);
  386.             for (j = 0; j < 3; j++)
  387.             {
  388.                 if ((tolower (q[j]) != tolower (r[j])) && (q[j] != '?'))
  389.                     break;
  390.             }
  391.             if (j == 3)
  392.                 user_exits[i] = 1;
  393.         }
  394.     }
  395.  
  396.     return (0);
  397. }
  398.  
  399. int 
  400. is_arcmail (char *p, int n)
  401. {
  402.     int i, l;
  403.     char c[128];
  404.  
  405.     l = n;
  406.     if (n < 0)
  407.         n = -n;
  408.  
  409.     if (!isdigit (p[n]))
  410.     {
  411.         return (l >= 0 ? is_user (p) : 0);
  412.     }
  413.  
  414.     (void) strcpy (c, p);
  415.     (void) strupr (c);
  416.  
  417.     for (i = n - 11; i < n - 3; i++)
  418.     {
  419.         if ((!isdigit (c[i])) && ((c[i] > 'F') || (c[i] < 'A')))
  420.             return (l >= 0 ? is_user (p) : 0);
  421.     }
  422.  
  423.     for (i = 0; i < 7; i++)
  424.     {
  425.         if (strnicmp (&c[n - 2], suffixes[i], 2) == 0)
  426.             break;
  427.     }
  428.  
  429.     if (i >= 7)
  430.     {
  431.         return (l > 0 ? is_user (p) : 0);
  432.     }
  433.  
  434.     if (l >= 0)
  435.         got_arcmail = 1;
  436.     return (1);
  437. }
  438.  
  439. int 
  440. get_number (char *target)
  441. {
  442.     ADDR gaddr;
  443.     int k;
  444.  
  445.     (void) fgets (target, 100, stdin);
  446.     k = (int) strlen (target);
  447.  
  448.     if (k == 1)
  449.         return (0);
  450.     target[--k] = '\0';            /* no '\n' */
  451.  
  452.     if (!isdigit (target[0]) && target[0] != '\"')
  453.     {
  454.         (*userfunc) (target, &gaddr);
  455.         if ((gaddr.Net != 0xffff) && (gaddr.Node != 0xffff) && (gaddr.Zone != 0xffff))
  456.         {
  457.             (void) sprintf (target, "%s", Full_Addr_Str (&gaddr));
  458.         }
  459.         else
  460.             return (0);            /* Gotta have addr */
  461.     }
  462.     return (1);
  463. }
  464.  
  465. void 
  466. gong ()
  467. {
  468.     long t;
  469.     int i;
  470.  
  471.     if (!gong_allowed)
  472.         return;
  473.  
  474.     for (i = 0; i < 15; i++)
  475.     {
  476.         WRITE_ANSI ('\07');        /* Bell code       */
  477.         t = timerset (100);        /* 1 second        */
  478.         while (!timeup (t))
  479.         {
  480.             if (KEYPRESS ())    /* If key pressed, */
  481.             {
  482.                 (void) READKB ();    /* Throw it away   */
  483.                 return;            /* And get out     */
  484.             }
  485.         }
  486.     }
  487. }
  488.  
  489. char *
  490. skip_blanks (char *string)
  491. {
  492.     while (*string && isspace (*string))
  493.         ++string;
  494.     return (string);
  495. }
  496.  
  497. char *
  498. skip_to_blank (char *string)
  499. {
  500.     while (*string && (!isspace (*string)))
  501.         ++string;
  502.     return (string);
  503. }
  504.  
  505. #ifdef DEBUG
  506. void 
  507. show_debug_name (char *string)
  508. {
  509.     int x, y;
  510.     static char *filler = "                           ";
  511.  
  512.     x = wherex ();
  513.     y = wherey ();
  514.     gotoxy (40, 0);
  515.     scr_printf (string);
  516.     scr_printf (&filler[strlen (string)]);
  517.     gotoxy (x, y);
  518. }
  519. #endif
  520.  
  521. int 
  522. parse (char *input, struct parse_list far list[])
  523. {
  524.     int i, j;
  525.     char *p;
  526.     char far *q;
  527.  
  528.     for (i = 0; list[i].p_length; i++)
  529.     {
  530.         p = input;
  531.         q = list[i].p_string;
  532.         for (j = list[i].p_length; j > 0; j--, p++, q++)
  533.         {
  534.             if (tolower (*p) != tolower (*q))
  535.                 break;
  536.         }
  537.         if (j == 0)
  538.             return (++i);
  539.     }
  540.     return (-1);
  541. }
  542.  
  543. void 
  544. change_prompt ()
  545. {
  546.     char *s;
  547.  
  548.     if (newstring[0])
  549.     {
  550.         (void) putenv (newstring);
  551.         return;
  552.     }
  553.  
  554.     (void) strcpy (newstring, "PROMPT=[");
  555.     (void) strcat (newstring, xfer_id);
  556.     (void) strcat (newstring, COMPILER_NAME);
  557.     (void) strcat (newstring, " Shell]$_");
  558.     s = getenv ("PROMPT");
  559.     if (s)
  560.     {
  561.         (void) strcat (newstring, s);
  562.     }
  563.     else
  564.     {
  565.         (void) strcat (newstring, "$P$G");
  566.     }
  567.  
  568.     (void) putenv (newstring);
  569. }
  570.  
  571. static char *last_str[] =
  572. {
  573.     "     None    ",
  574.     "     WaZOO   ",
  575.     "     FTS-0001",
  576.     "     BBS     ",
  577.     "     Ext Mail",
  578.     "     FAX     "
  579. };
  580.  
  581. void 
  582. last_type (int n, ADDRP taddr)
  583. {
  584.     int i;
  585.     char *p;
  586.     char j[90];
  587.  
  588.     if (fullscreen)
  589.         sb_move (historywin, HIST_LAST_ROW, HIST_COL2);
  590.  
  591.     if ((n == 1) || (n == 2))
  592.     {
  593.         if (((int) taddr->Zone != -1000) && ((int) taddr->Net > 0))
  594.         {
  595.             (void) sprintf (j, "%s", Full_Addr_Str (taddr));
  596.             if ((p = strchr (j, '@')) != NULL)
  597.                 *p = '\0';
  598.             for (i = (int) strlen (j); i < 14; i++)
  599.                 j[i] = ' ';
  600.             j[i] = '\0';
  601.             hist.last_addr = *taddr;
  602.         }
  603.         else
  604.         {
  605.             (void) strcpy (j, "     FTS-0001");
  606.         }
  607.         if (fullscreen)
  608.         {
  609.             sb_puts (historywin, j);
  610.         }
  611.     }
  612.     else
  613.     {
  614.         if ((n < 0) || (n > 5))
  615.             n = 0;
  616.  
  617.         if (fullscreen)
  618.             sb_puts (historywin, last_str[n]);
  619.     }
  620.  
  621.     hist.last_caller = (short) n;
  622. }
  623.  
  624. /*--------------------------------------------------------------------------*/
  625. /* CHECK_NETFILE -- find out if the file we've got is a netfile.            */
  626. /*--------------------------------------------------------------------------*/
  627.  
  628. char *
  629. check_netfile (char *fname)
  630. {
  631.     register char *p;
  632.     register int n;
  633.  
  634.     p = fname;
  635.     n = (int) strlen (p) - 1;
  636.  
  637.     if ((p[n] == 't') && (p[n - 1] == 'k') && (p[n - 2] == 'p') && (p[n - 3] == '.'))
  638.     {
  639.         got_packet = 1;
  640.         got_mail = 1;
  641.         p = MSG_TXT (M_MAIL_PACKET);
  642.     }
  643.     else if (is_arcmail (p, n))
  644.     {
  645.         got_mail = 1;
  646.         p = MSG_TXT (M_COMPRESSED_MAIL);
  647.     }
  648.     else
  649.     {
  650.         short mytask = -1;
  651.  
  652.         if (p[n - 2] != 'R' || p[n - 3] != '.')
  653.             got_mail = 1;
  654.         else
  655.         {
  656.             sscanf (&p[n - 1], "%02hx", &mytask);
  657.             if (mytask != TaskNumber)
  658.                 got_mail = 1;
  659.         }
  660.         p = MSG_TXT (M_NET_FILE);
  661.     }
  662.  
  663.     return (p);
  664. }
  665.  
  666. /*--------------------------------------------------------------------------*/
  667. /* UNIQUE_NAME                                                              */
  668. /* Increments the suffix of a filename as necessary to make the name unique */
  669. /*--------------------------------------------------------------------------*/
  670. void 
  671. unique_name (char *fname)
  672. {
  673.     static char suffix[] = ".001";
  674.     register char *p;
  675.     register int n;
  676.  
  677.     if (dexists (fname))
  678.     {                            /* If file already exists...      */
  679.         p = fname;
  680.         while (*p && *p != '.')
  681.             p++;                /* ...find the extension, if
  682.                                                   * any  */
  683.         for (n = 0; n < 4; n++)    /* ...fill it out if
  684.                                                   * neccessary   */
  685.             if (!*p)
  686.             {
  687.                 *p = suffix[n];
  688.                 *(++p) = '\0';
  689.             }
  690.             else
  691.                 p++;
  692.  
  693.         while (dexists (fname))    /* ...If 'file.ext' exists
  694.                                                   * suffix++ */
  695.         {
  696.             p = fname + strlen (fname) - 1;
  697.             for (n = 3; n--;)
  698.             {
  699.                 if (!isdigit (*p))
  700.                     *p = '0';
  701.                 if (++(*p) <= '9')
  702.                     break;
  703.                 else
  704.                     *p-- = '0';
  705.             }                    /* for */
  706.         }                        /* while */
  707.     }                            /* if exist */
  708. }                                /* unique_name */
  709.  
  710. int 
  711. got_ESC ()
  712. {
  713.     while (KEYPRESS ())
  714.     {
  715.         screen_blank = 0;
  716.         if (fullscreen && un_attended)
  717.             sb_show ();
  718.         if (READKB () == 27)    /* ESC pressed?        */
  719.         {
  720.             while (KEYPRESS ())
  721.                 (void) READKB ();
  722.             return (1);
  723.         }
  724.     }
  725.     return (0);
  726. }
  727.  
  728. long 
  729. cost_of_call (int caller, long s, long e)
  730. {
  731.     long a = 0;
  732.     char *p;
  733.     char logline[34];
  734.     word cost;
  735.     int session = 0;
  736.  
  737.     int infiles, outfiles, totfiles;
  738.     long insize, outsize, totsize;
  739.     long intime, outtime, tottime;
  740.     long incps, outcps, totcps;
  741.     long ineff, outeff, toteff;
  742.     long inerr, outerr, toterr;
  743.  
  744.     char costfmt[] = "%s Stat %4s %3hd Files (%s)%5ldcps %3hd%%  Err: %ld\n";
  745.  
  746.     sprintf (logline, "%02i %03s %02i:%02i",
  747.         tp->tm_mday, mtext[tp->tm_mon], tp->tm_hour,
  748.         tp->tm_min, Full_Addr_Str (&remote_addr));
  749.  
  750.     e = (e - s) + 5;
  751.  
  752.     cost = (caller != 0) ? newnodedes.RealCost : 0;
  753.  
  754.     if (caller || hist.last_caller == 1 || hist.last_caller == 2)
  755.     {
  756.         session = 1;
  757.         p = Full_Addr_Str (&remote_addr);
  758.     }
  759.     else
  760.     {
  761.         if (hist.last_caller == 3)
  762.             p = "BBS";
  763.         else if (hist.last_caller == 4)
  764.             p = "Ext Mail";
  765.         else if (hist.last_caller == 5)
  766.             p = "FAX";
  767.         else p = "Unknown";
  768.     }
  769.  
  770.     if (cost != 0)
  771.     {
  772.         if (eurocost)
  773.             a = ((e * 10 + cost - 1) / cost) * cost_unit;
  774.         else
  775.         {
  776.             long e2 = (e + 59) / 60;
  777.             a = e2 * cost;
  778.         }
  779.     }
  780.  
  781.     infiles = hist.files_in - start_hist.files_in;
  782.     outfiles = hist.files_out - start_hist.files_out;
  783.     totfiles = infiles + outfiles;
  784.  
  785.     insize = hist.size_in - start_hist.size_in;
  786.     outsize = hist.size_out - start_hist.size_out;
  787.     totsize = insize + outsize;
  788.  
  789.     intime = hist.time_in - start_hist.time_in;
  790.     outtime = hist.time_out - start_hist.time_out;
  791.     tottime = e;
  792.  
  793.     inerr = hist.err_in - start_hist.err_in;
  794.     outerr = hist.err_out - start_hist.err_out;
  795.     toterr = inerr + outerr;
  796.  
  797.     start_hist = hist;
  798.  
  799.     incps = (intime) ? (insize / intime) : 0;
  800.     outcps = (outtime) ? (outsize / outtime) : 0;
  801.     totcps = (tottime) ? (totsize / tottime) : 0;
  802.  
  803.     ineff = incps * 1000L / cur_baud.rate_value;
  804.     outeff = outcps * 1000L / cur_baud.rate_value;
  805.     toteff = totcps * 1000L / cur_baud.rate_value;
  806.  
  807.     if (session && cost_log != NULL)
  808.     {
  809.         fprintf (cost_log, costfmt, logline, "Sent ",
  810.             (outfiles > 999) ? 999 : outfiles,
  811.             numdisp (outsize), outcps, outeff,
  812.             outerr);
  813.         fprintf (cost_log, costfmt, logline, "Rcvd ",
  814.             (infiles > 999) ? 999 : infiles,
  815.             numdisp (insize), incps, ineff,
  816.             inerr);
  817.         fprintf (cost_log, costfmt, logline, "Total",
  818.             (totfiles > 999) ? 999 : totfiles,
  819.             numdisp (totsize), totcps, toteff,
  820.             toterr);
  821.  
  822.         fprintf (cost_log, "%s Seconds: %ld  Cost: %ld  System: %s\n\n",
  823.             logline, e, a, Full_Addr_Str (&remote_addr));
  824.         fflush (cost_log);
  825.         real_flush (fileno (cost_log));
  826.     }
  827.  
  828.     if (session)
  829.     {
  830.         status_line (MSG_TXT (M_BYTE_SUMMARY),
  831.             infiles, insize, outfiles, outsize, totfiles, totsize, totcps);
  832.     }
  833.  
  834.     status_line (MSG_TXT (M_COST_SUMMARY), e, cost, a, p);
  835.  
  836.     if (modem_aftercall && remote_pickup != -2)
  837.     {
  838.         int i = 0;
  839.         long lwait;
  840.  
  841.         mdm_cmd_string (modem_aftercall, 0);
  842.  
  843.         lwait = timerset (300);
  844.         for (i = 0; i < lines_aftercall && !timeup (lwait); i++)
  845.         {
  846.             if (!stricmp (get_response (lwait), "NO CARRIER"))
  847.             {
  848.                 CLEAR_INBOUND ();
  849.                 break;
  850.             }
  851.             lwait = timerset (100);
  852.         }
  853.     }
  854.  
  855.     return (a);
  856. }
  857.  
  858. /*
  859.  * Create a small character string for mailsize and cost_of_call.
  860.  */
  861.  
  862. static char e_stuff[6];
  863. static char *rgchSize = "bKMG";
  864.  
  865. char *
  866. numdisp (long number)
  867. {
  868.     int i = 0;
  869.     char tempstr[6];
  870.     long quotient, oldq;
  871.     int intq;
  872.  
  873.     oldq = 0L;
  874.     quotient = number;
  875.  
  876.     while (quotient >= 1024L)
  877.     {
  878.         oldq = quotient;
  879.         quotient = oldq / 1024L;
  880.         i++;
  881.     }
  882.  
  883.     intq = (int) quotient;
  884.  
  885.   /*
  886.    * If more than 999 but less than 1024, it's a big fraction of
  887.    * the next power of 1024. Get top two significant digits
  888.    * (so 1023 would come out .99K, for example)
  889.    */
  890.  
  891.     if (intq > 999)
  892.     {
  893.         intq = (intq * 25) / 256;    /* 100/1024 */
  894.         (void) sprintf (e_stuff, ".%2d%c", intq, rgchSize[++i]);
  895.     }
  896.  
  897.   /*
  898.    * If less than 10 and not small units, then get some decimal
  899.    * places (e.g. 1.2M)
  900.    */
  901.  
  902.     else if ((intq < 10) && (i != 0))
  903.     {
  904.         intq = (int) ((oldq * 5L) / 512L);    /* 10/1024 */
  905.         (void) sprintf (tempstr, "%02d", intq);
  906.         (void) sprintf (e_stuff, "%c.%c%c", tempstr[0], tempstr[1], rgchSize[i]);
  907.     }
  908.  
  909.   /*
  910.    * Simple case. Just do it.
  911.    */
  912.  
  913.     else
  914.         (void) sprintf (e_stuff, "%3d%c", intq, rgchSize[i]);
  915.  
  916.     return (e_stuff);
  917. }
  918.  
  919. void
  920. update_files (int sender, char *filename, long filesize, long filetime, long err)
  921. {
  922.     if (un_attended)
  923.     {
  924.         if (sender)
  925.         {
  926.             ++hist.files_out;
  927.             hist.size_out += filesize;
  928.             hist.time_out += filetime;
  929.             hist.err_out += err;
  930.         }
  931.         else
  932.         {
  933.             ++hist.files_in;
  934.             hist.size_in += filesize;
  935.             hist.time_in += filetime;
  936.             hist.err_in += err;
  937.         }
  938.     }
  939.  
  940.     if (un_attended && fullscreen)
  941.     {
  942.         char s[10];
  943.  
  944.         (void) sprintf (s, "%d/%d", hist.files_in, hist.files_out);
  945.         sb_move (historywin, HIST_FILE_ROW, HIST_COL);
  946.         sb_puts (historywin, s);
  947.         sb_show ();
  948.     }
  949.  
  950.     if ((cost_log != NULL) && isOriginator)
  951.     {
  952.         char *pszMode = (sender ? "Sent" : "Received");
  953.  
  954.         ltime = time (NULL);
  955.         tp = localtime (<ime);
  956.  
  957.         fprintf (cost_log, "%02i %03s %02i:%02i %s: %s (%ld)\n",
  958.             tp->tm_mday, mtext[tp->tm_mon], tp->tm_hour, tp->tm_min,
  959.             pszMode, filename, filesize);
  960.         fflush (cost_log);
  961.         real_flush (fileno (cost_log));
  962.     }
  963. }
  964.  
  965. void 
  966. screen_clear ()
  967. {
  968.     unsigned int r;
  969.     PCH q;
  970.  
  971.     if (!vfossil_installed)
  972.         scr_printf ("\033[H\033[2J");
  973.     else
  974.     {
  975.         for (r = 0; (int) r <= (int) SB_ROWS; r++)
  976.         {
  977.             q = (PCH) blanks;
  978.             (void) VioWrtCellStr ((PCH) q, (USHORT) (SB_COLS * 2), (USHORT) r, (USHORT) 0, (HVIO) 0L);
  979.         }
  980.  
  981.         gotoxy (0, 0);
  982.     }
  983. }
  984.  
  985. void 
  986. clear_eol ()
  987. {
  988.     unsigned int x, y;
  989.     PCH q;
  990.  
  991.     if (!vfossil_installed)
  992.         (void) printf ("\033[K");
  993.     else
  994.     {
  995.         x = (unsigned int) wherex ();
  996.         y = (unsigned int) wherey ();
  997.  
  998.         q = (PCH) blanks;
  999.         (void) VioWrtCellStr ((PCH) q, (USHORT) ((SB_COLS - x) * 2), (USHORT) y, (USHORT) x, (HVIO) 0L);
  1000.     }
  1001. }
  1002.  
  1003. void 
  1004. log_product (int product, int version, int subversion)
  1005. {
  1006.     switch (product)
  1007.     {
  1008.  
  1009.     /*  Special case Opus. */
  1010.     case isOPUS:
  1011.         status_line ("%s Opus %s %d.%02d", MSG_TXT (M_REMOTE_USES),
  1012.             MSG_TXT (M_VERSION), version,
  1013.             (subversion == 48) ? 0 : subversion);
  1014.         break;
  1015.  
  1016.     default:
  1017.         status_line ("%s %s %s %d.%02d", MSG_TXT (M_REMOTE_USES),
  1018.             PRDCT_NM (product), MSG_TXT (M_VERSION), version, subversion);
  1019.         break;
  1020.     }
  1021.     return;
  1022. }
  1023.  
  1024. int 
  1025. next_minute ()
  1026. {
  1027.     time_t long_time;
  1028.     struct tm *tm;
  1029.  
  1030.     /* Get the current time into a structure */
  1031.  
  1032.     (void) time (&long_time);
  1033.     tm = localtime (&long_time);
  1034.  
  1035.     return ((60 - (tm->tm_sec % 60)) * 100 + 1);
  1036. }
  1037.  
  1038. void 
  1039. can_Janus (char *p)
  1040. {
  1041.     J_TYPESP j;
  1042.  
  1043.     janus_OK = 0;
  1044.     for (j = j_top; j != NULL; j = j->next)
  1045.     {
  1046.         if (strnicmp (p, j->j_match, strlen (j->j_match)) == 0)
  1047.         {
  1048.             janus_OK = 1;
  1049.             break;
  1050.         }
  1051.     }
  1052. }
  1053.  
  1054. int 
  1055. check_failed (char *fname, char *theirname, char *info, char *ourname)
  1056. {
  1057.     FILE *abortlog;
  1058.     char linebuf[64];
  1059.     char *p, *badname;
  1060.     int ret;
  1061.  
  1062.     ret = 0;
  1063.     if ((abortlog = fopen (fname, read_ascii)) == NULL)
  1064.     {
  1065.         (void) got_error (MSG_TXT (M_OPEN_MSG), fname);
  1066.     }
  1067.     else
  1068.     {
  1069.         while (!feof (abortlog))
  1070.         {
  1071.             linebuf[0] = '\0';
  1072.             if (!fgets ((p = linebuf), 64, abortlog))
  1073.                 break;
  1074.             while (*p >= ' ')
  1075.                 ++p;
  1076.             *p = '\0';
  1077.             p = strchr (linebuf, ' ');
  1078.             *p = '\0';
  1079.             if (!stricmp (linebuf, theirname))
  1080.             {
  1081.                 p = strchr ((badname = ++p), ' ');
  1082.                 *p = '\0';
  1083.                 if (!stricmp (++p, info))
  1084.                 {
  1085.                     (void) strcpy (ourname, badname);
  1086.                     ret = 1;
  1087.                     break;
  1088.                 }
  1089.             }
  1090.         }
  1091.         (void) fclose (abortlog);
  1092.     }
  1093.  
  1094.     return (ret);
  1095. }
  1096.  
  1097. void 
  1098. add_abort (char *fname, char *rname, char *cname,
  1099.     char *cpath, char *info)
  1100. {
  1101.     FILE *abortlog;
  1102.     char namebuf[100];
  1103.  
  1104.     (void) strcpy (namebuf, cpath);
  1105.     (void) strcat (namebuf, "BadWaZOO.001");
  1106.     unique_name (namebuf);
  1107.     (void) rename (cname, namebuf);
  1108.     if ((abortlog = fopen (fname, append_ascii)) == NULL)
  1109.     {
  1110.         (void) got_error (MSG_TXT (M_OPEN_MSG), fname);
  1111.         (void) unlink (namebuf);
  1112.     }
  1113.     else
  1114.     {
  1115.         (void) fprintf (abortlog, "%s %s %s\n", rname, namebuf + strlen (cpath), info);
  1116.         (void) fclose (abortlog);
  1117.     }
  1118. }
  1119.  
  1120. void 
  1121. remove_abort (char *fname, char *rname)
  1122. {
  1123.     FILE *abortlog, *newlog;
  1124.     char namebuf[100];
  1125.     char linebuf[100];
  1126.     char *p;
  1127.     int c;
  1128.  
  1129.     if (!dexists (fname))
  1130.         return;
  1131.  
  1132.     if ((abortlog = fopen (fname, read_ascii)) == NULL)
  1133.     {
  1134.         (void) got_error (MSG_TXT (M_OPEN_MSG), fname);
  1135.     }
  1136.     else
  1137.     {
  1138.         (void) strcpy (namebuf, fname);
  1139.         (void) strcpy (namebuf + strlen (namebuf) - 1, "TMP");
  1140.         c = 0;
  1141.         if ((newlog = fopen (namebuf, write_ascii)) == NULL)
  1142.         {
  1143.             (void) got_error (MSG_TXT (M_OPEN_MSG), namebuf);
  1144.             (void) fclose (abortlog);
  1145.         }
  1146.         else
  1147.         {
  1148.             while (!feof (abortlog))
  1149.             {
  1150.                 linebuf[0] = '\0';
  1151.                 if (!fgets (linebuf, 64, abortlog))
  1152.                     break;
  1153.                 p = linebuf;
  1154.                 while (*p > ' ')
  1155.                     ++p;
  1156.                 *p = '\0';
  1157.                 if (stricmp (linebuf, rname))
  1158.                 {
  1159.                     *p = ' ';
  1160.                     (void) fputs (linebuf, newlog);
  1161.                     ++c;
  1162.                 }
  1163.             }
  1164.             (void) fclose (abortlog);
  1165.             (void) fclose (newlog);
  1166.             (void) unlink (fname);
  1167.             if (c)
  1168.                 (void) rename (namebuf, fname);
  1169.             else
  1170.                 (void) unlink (namebuf);
  1171.         }
  1172.     }
  1173. }
  1174.  
  1175. /*
  1176.  * The next routine is used in the count down timer during file
  1177.  * transfers, and were provided by Jon Sabol, along with the other code that
  1178.  * calls these routines.
  1179.  */
  1180.  
  1181. void 
  1182. elapse_time ()
  1183. {
  1184.     time_t lTimeT;
  1185.     time_t etime;
  1186.     long eh;
  1187.     long em;
  1188.     long es;
  1189.  
  1190.     if (fullscreen && (un_attended || doing_poll))
  1191.     {
  1192.         (void) time (&lTimeT);
  1193.  
  1194.         if (lTimeT < etm)
  1195.             lTimeT += 86400L;
  1196.         etime = lTimeT - etm;
  1197.         eh = etime / 3600L;
  1198.         em = (etime / 60L) - (eh * 60L);
  1199.         es = etime - (eh * 3600L) - (em * 60L);
  1200.  
  1201.         (void) sprintf (junk,
  1202.             "%s:  %02ld:%02ld:%02ld ",
  1203.             MSG_TXT (M_ELAPSED),
  1204.             eh, em, es);
  1205.         sb_move (settingswin, SET_TASK_ROW, SET_TIME_COL);
  1206.         sb_puts (settingswin, junk);
  1207.         sb_show ();
  1208.     }
  1209. }
  1210.  
  1211. static int LOCALFUNC 
  1212. find_addr (char *node, ADDRP addr, char *d)
  1213. {
  1214.     int ret;
  1215.  
  1216.     ret = 1;
  1217.     if (alias[0].Node == 0xffff)
  1218.         addr->Zone = 0;
  1219.     else
  1220.         addr->Zone = alias[0].Zone;
  1221.     addr->Net = 0;
  1222.     addr->Node = 0;
  1223.     addr->Point = 0;
  1224.     addr->Domain = NULL;
  1225.     d[0] = '\0';
  1226.     if ((ret = sscanf (node, "%hd:%hd/%hd.%hd@%s",
  1227.                 &(addr->Zone), &(addr->Net), &(addr->Node), &(addr->Point), d)) < 3)
  1228.     {
  1229.         if (alias[0].Node == 0xffff)
  1230.             addr->Zone = 0;
  1231.         else
  1232.             addr->Zone = alias[0].Zone;
  1233.         d[0] = '\0';
  1234.         if ((ret = sscanf (node, "%hd/%hd.%hd@%s",
  1235.                     &(addr->Net), &(addr->Node), &(addr->Point), d)) < 2)
  1236.         {
  1237.             addr->Net = alias[0].Net;
  1238.             d[0] = '\0';
  1239.             if (sscanf (node, "%hd.%hd@%s",
  1240.                     &(addr->Node), &(addr->Point), d) < 1)
  1241.             {
  1242.                 if ((ret = sscanf (node, ".%hd@%s", &(addr->Point), d)) > 0)
  1243.                 {
  1244.                     addr->Node = alias[0].Node;
  1245.                 }
  1246.             }
  1247.             else if (ret == 1)
  1248.             {
  1249.                 d[0] = '\0';
  1250.                 (void) sscanf (node, "%hd@%s",
  1251.                     &(addr->Node), d);
  1252.             }
  1253.         }
  1254.         else if (ret == 2)
  1255.         {
  1256.             d[0] = '\0';
  1257.             (void) sscanf (node, "%hd/%hd@%s",
  1258.                 &(addr->Net), &(addr->Node), d);
  1259.         }
  1260.     }
  1261.     else if (ret == 3)
  1262.     {
  1263.         d[0] = '\0';
  1264.         (void) sscanf (node, "%hd:%hd/%hd@%s",
  1265.             &(addr->Zone), &(addr->Net), &(addr->Node), d);
  1266.     }
  1267.  
  1268.     return (ret);
  1269. }
  1270.  
  1271. int 
  1272. parse_address (char *node, ADDRP addr)
  1273. {
  1274.     int ret;
  1275.     char d[100];
  1276.  
  1277.     ret = find_addr (node, addr, d);
  1278.  
  1279.     if (d[0] != '\0')
  1280.     {
  1281.         addr->Domain = add_domain (d);
  1282.     }
  1283.     else
  1284.         addr->Domain = NULL;
  1285.  
  1286.     return (ret);
  1287. }
  1288.  
  1289. int 
  1290. find_address (char *node, ADDRP addr)
  1291. {
  1292.     int i;
  1293.     int ret;
  1294.     char d[255];
  1295.     char *p;
  1296.  
  1297.     d[0] = '\0';
  1298.     p = skip_blanks (node);
  1299.     if (!isdigit (*p) && (*p != '.'))
  1300.     {
  1301.         (*userfunc) (p, addr);
  1302.         if ((addr->Net == 0xffff) || (addr->Node == 0xffff) || (addr->Zone == 0xffff))
  1303.         {
  1304.             ret = 0;
  1305.         }
  1306.         else
  1307.         {
  1308.             ret = 1;
  1309.         }
  1310.     }
  1311.     else
  1312.     {
  1313.         ret = find_addr (p, addr, d);
  1314.     }
  1315.  
  1316.     if (d[0] != '\0' && domain_name[0] != NULL)
  1317.     {
  1318.         addr->Domain = add_domain (d);
  1319.     }
  1320.     else
  1321.     {
  1322.         addr->Domain = domain_name[0];
  1323.         for (i = 0; i < num_domain_kludge; i++)
  1324.         {
  1325.             if (addr->Zone == domainkludge[i].zone)
  1326.             {
  1327.                 addr->Domain = domain_name[domainkludge[i].domain];
  1328.                 break;
  1329.             }
  1330.         }
  1331.     }
  1332.  
  1333.     return (ret);
  1334. }
  1335.  
  1336. char *
  1337. add_domain (char *d)
  1338. {
  1339.     char *p, *q;
  1340.     int i;
  1341.  
  1342.     for (i = 0; (p = domain_name[i]) != NULL; i++)
  1343.     {
  1344.         if (strnicmp (d, p, strlen (p)) == 0)
  1345.             return (p);
  1346.         q = domain_abbrev[i];
  1347.         if (q == NULL)            /* This can happen if no "Domain" line... */
  1348.             continue;
  1349.         if (strnicmp (d, q, strlen (q)) == 0)
  1350.             return (p);
  1351.     }
  1352.  
  1353.     if (i >= 49)
  1354.         return (NULL);
  1355.  
  1356.     domain_name[i] = strdup (d);
  1357.     return (domain_name[i]);
  1358. }
  1359.  
  1360. char *
  1361. find_domain (char *d)
  1362. {
  1363.     char *p, *q, *s;
  1364.     char c;
  1365.     int i, j, k;
  1366.  
  1367.     j = strlen (d);
  1368.     /* First see if we can find the whole domain name at the right */
  1369.     for (i = 0; (p = domain_name[i]) != NULL; i++)
  1370.     {
  1371.         k = strlen (p);
  1372.         if (k > j)
  1373.             continue;
  1374.  
  1375.         q = &(d[j - k]);
  1376.         if (strnicmp (q, p, k) == 0)
  1377.         {
  1378.             return (p);
  1379.         }
  1380.     }
  1381.  
  1382.     /* Ok, now see if we can find the abbreviated name at the right */
  1383.     for (i = 0; (p = domain_abbrev[i]) != NULL; i++)
  1384.     {
  1385.         k = strlen (p);
  1386.         if (k > j)
  1387.             continue;
  1388.  
  1389.         q = &(d[j - k]);
  1390.         if (strnicmp (q, p, k) == 0)
  1391.         {
  1392.             return (domain_name[i]);
  1393.         }
  1394.     }
  1395.  
  1396.     /* If there is a period in it, see if we can match the abbreviated name
  1397.       just before the period */
  1398.     if ((s = strrchr (d, '.')) != NULL)
  1399.     {
  1400.         c = *s;
  1401.         *s = '\0';
  1402.         j = strlen (d);
  1403.         for (i = 0; (p = domain_abbrev[i]) != NULL; i++)
  1404.         {
  1405.             k = strlen (p);
  1406.             if (k > j)
  1407.                 continue;
  1408.  
  1409.             q = &(d[j - k]);
  1410.             if (strnicmp (q, p, k) == 0)
  1411.             {
  1412.                 *s = c;
  1413.                 return (domain_name[i]);
  1414.             }
  1415.         }
  1416.         *s = c;
  1417.     }
  1418.  
  1419.     return (NULL);
  1420. }
  1421.  
  1422. char addr_str[100];
  1423.  
  1424. char *
  1425. Hex_Addr_Str (ADDRP a)
  1426. {
  1427.     if (a->Point != 0)
  1428.     {
  1429.         (void) sprintf (addr_str, "%04hx%04hx.PNT\\%08hx", a->Net, a->Node, a->Point);
  1430.     }
  1431.     else
  1432.         (void) sprintf (addr_str, "%04hx%04hx", a->Net, a->Node);
  1433.     return (addr_str);
  1434. }
  1435.  
  1436. char *
  1437. Full_Addr_Str (ADDRP a)
  1438. {
  1439.     char t1[10];
  1440.     char t2[30];
  1441.     char t3[10];
  1442.     char t4[50];
  1443.  
  1444.     if (a->Zone && !no_zones)
  1445.         (void) sprintf (t1, "%hu:", a->Zone);
  1446.     else
  1447.         t1[0] = '\0';
  1448.  
  1449.     (void) sprintf (t2, "%hu/%hu", a->Net, a->Node);
  1450.  
  1451.     if (a->Point)
  1452.         (void) sprintf (t3, ".%hu", a->Point);
  1453.     else
  1454.         t3[0] = '\0';
  1455.  
  1456.     if (a->Domain != NULL)
  1457.         (void) sprintf (t4, "@%s", a->Domain);
  1458.     else
  1459.         t4[0] = '\0';
  1460.  
  1461.     (void) strcpy (addr_str, t1);
  1462.     (void) strcat (addr_str, t2);
  1463.     (void) strcat (addr_str, t3);
  1464.     (void) strcat (addr_str, t4);
  1465.     return (addr_str);
  1466. }
  1467.  
  1468. unsigned short
  1469. crc_block (unsigned char *ptr, int count)
  1470. {
  1471.     register word crc;
  1472.     int i;
  1473.  
  1474.     for (crc = 0, i = 0; i < count; i++, ptr++)
  1475.     {
  1476.         crc = xcrc (crc, (byte) * ptr);
  1477.     }
  1478.     return (crc);
  1479. }
  1480.  
  1481. void 
  1482. Data_Check (XMDATAP xtmp, int mode)
  1483. {
  1484.     int i;
  1485.     unsigned char cs;
  1486.     unsigned char *cp;
  1487.     unsigned short cs1;
  1488.  
  1489.     /* If we are in checksum mode, just do it */
  1490.     if (mode == CHECKSUM)
  1491.     {
  1492.         cp = xtmp->data_bytes;
  1493.         cs = 0;
  1494.         for (i = 0; i < 128; i++)
  1495.         {
  1496.             cs += *cp++;
  1497.         }
  1498.         xtmp->data_check[0] = cs;
  1499.     }
  1500.     /* If we are in CRC mode, run the characters through the CRC calculator */
  1501.     else
  1502.     {
  1503.         cs1 = crc_block (xtmp->data_bytes, 128);
  1504.         xtmp->data_check[0] = (unsigned char) (cs1 >> 8);
  1505.         xtmp->data_check[1] = (unsigned char) (cs1 & 0xff);
  1506.     }
  1507. }
  1508.  
  1509. void 
  1510. wait_for_key (int ts)
  1511. {
  1512.     long t_idle;
  1513.  
  1514.     sb_show ();
  1515.     t_idle = timerset (ts);
  1516.     while (!timeup (t_idle) && (PEEKBYTE () == -1) && !(KEYPRESS ()))
  1517.         time_release ();
  1518.     if (KEYPRESS ())
  1519.         ts = (int) FOSSIL_CHAR ();
  1520. }
  1521.